package com.relytosoft.mizar.media.display.services.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.mizar.media.camera.api.entity.CameraPlatform;
import com.relytosoft.mizar.media.camera.api.feign.CameraFeignInService;
import com.relytosoft.mizar.media.common.constant.MediaMqConstants;
import com.relytosoft.mizar.media.common.emqx.client.MqttOp;
import com.relytosoft.mizar.media.display.api.entity.Preset;
import com.relytosoft.mizar.media.display.api.pojo.dto.PtzPresetDto;
import com.relytosoft.mizar.media.display.services.mapper.PresetMapper;
import com.relytosoft.mizar.media.display.services.service.PresetService;
import com.relytosoft.mizar.media.display.services.utils.ResponseUtils;
import com.relytosoft.mizar.media.external.api.display.request.PresetDto;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.relytosoft.mizar.media.display.services.constants.OperationConstant.*;

/**
 * 预置位业务实现类
 *
 * @author hj
 * @version 1.0
 * @date 2022/4/6 14:01
 * @ClassName PresetServiceImpl
 */
@Service
public class PresetServiceImpl extends ServiceImpl<PresetMapper, Preset> implements PresetService {
    public static final int MAX_SIZE = 20;
    @Resource
    private CameraFeignInService cameraFeignInService;

    @Override
    public IPage<Preset> selectPresetPageList(PageQuery pageQuery, Preset preset) {
        LambdaQueryWrapper<Preset> wrapper = Wrappers.lambdaQuery();
        if(StrUtil.isBlank(pageQuery.getOrderByColumn())) {
            pageQuery.setOrderByColumn("CREATED_TIME");
            pageQuery.setIsAsc("desc");
        }
        return this.page(pageQuery.build(), wrapper);
    }

    @Override
    public List<Preset> selectPresetList(Preset preset) {
        LambdaQueryWrapper<Preset> wrapper = Wrappers.lambdaQuery();
        Integer id = preset.getId();
        Integer presetIndex = preset.getPresetIndex();
        Integer channelId = preset.getChannelId();
        String presetName = preset.getPresetName();
        Integer isGuard = preset.getIsGuard();
        wrapper.eq(Objects.nonNull(id),Preset::getId,id)
                .eq(Objects.nonNull(presetIndex),Preset::getPresetIndex,presetIndex)
                .eq(Objects.nonNull(channelId),Preset::getChannelId,channelId)
                .like(StrUtil.isNotBlank(presetName),Preset::getPresetName,presetName)
                .eq(Objects.nonNull(isGuard),Preset::getIsGuard,isGuard);
        return list(wrapper);
    }

    /**
     * 删除预置位信息
     * @param id
     * @return boolean
     * @author jgg
     * @date 2022/4/6 14:35
     */
    @Override
    public boolean deleteById(Integer id) {
        Preset preset = getById(id);
        ResponseResult result = cameraFeignInService.findById(preset.getChannelId());
        PresetDto dto = new PresetDto(ResponseUtils.getCameraIndex(result), preset.getPresetIndex());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("OpType", DELETE);
        jsonObject.put("Data", JSON.toJSONString(dto));
        MqttOp.publish(MediaMqConstants.DISPLAY_PRESET_TOPIC, JSON.toJSONString(jsonObject));
        return removeById(id);
    }

    /**
     * 更新预置位信息
     *
     * @param dto
     * @return boolean
     * @author jgg
     * @date 2022/4/6 14:58
     */
    @Override
    public boolean updateByPreset(PtzPresetDto dto) {
        Preset preset = dto.buildEntity();
        visitPlat(preset, UPDATE);
        return updateById(preset);
    }



    /**
     * 添加预置位信息
     *
     * @param dto
     * @return boolean
     * @author jgg
     * @date 2022/4/6 15:00
     */
    @Override
    public boolean addPreset(PtzPresetDto dto) {
        Preset preset = dto.buildEntity();
        Preset one = hasPreset(preset);
        boolean save;
        if(Objects.isNull(one)){
            save = save(preset);
        }else {
            preset.setId(one.getId());
            save = updateById(preset);
        }
        visitPlat(preset, INSERT);
        return save ;
    }

   private Preset hasPreset(Preset preset){
       LambdaQueryWrapper<Preset> wrapper = Wrappers.lambdaQuery();
       Integer channelId = preset.getChannelId();
       Integer presetIndex = preset.getPresetIndex();
       wrapper.eq(Objects.nonNull(channelId),Preset::getChannelId,channelId)
               .eq(Objects.nonNull(presetIndex),Preset::getPresetIndex,presetIndex);
        Preset one = getOne(wrapper);
        if(Objects.isNull(one) ){
            return null;
        }
        return one;
    }

    private void visitPlat(Preset preset, String update) {
        ResponseResult<CameraPlatform> result = cameraFeignInService.findById(preset.getChannelId());
        PresetDto dto = new PresetDto(ResponseUtils.getCameraIndex(result), preset.getPresetName(), preset.getPresetIndex());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("OpType", update);
        jsonObject.put("Data", JSON.toJSONString(dto));
        MqttOp.publish(MediaMqConstants.DISPLAY_PRESET_TOPIC, JSON.toJSONString(jsonObject));
    }


    /**
     * 通过通道id查询预置位信息
     *
     * @param id
     * @return List<PtzPresetDto>
     * @author jgg
     */
    @Override
    public List<PtzPresetDto> selectPresetListById(Integer id) {
        LambdaQueryWrapper<Preset> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Preset::getChannelId,id)
                .orderByAsc(Preset::getPresetIndex);
        List<PtzPresetDto> ptzPresetDtoList = list(wrapper).parallelStream().map(PtzPresetDto::buildDto).collect(Collectors.toList());
        if (ptzPresetDtoList.size() < MAX_SIZE){
            List<Integer> indexList= ptzPresetDtoList.parallelStream().map(PtzPresetDto::getPresetIndex).collect(Collectors.toList());
            for(int i = 1 ; i <= MAX_SIZE ; i++){
                if (!indexList.contains(i)){
                    ptzPresetDtoList.add(i-1,new PtzPresetDto(i,id));
                }
            }
        }
        return ptzPresetDtoList;
    }
}
